package org.yanfengying.user.service.impl;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.yanfengying.dto.BinderDTO;
import org.yanfengying.dto.PasswordDTO;
import org.yanfengying.dto.PhoneLoginDTO;
import org.yanfengying.dto.RegisterSmsDTO;
import org.yanfengying.user.domain.Logininfo;
import org.yanfengying.user.mapper.LogininfoMapper;
import org.yanfengying.user.service.IVerifyCodeService;
import org.yanfengying.utils.SmsUtil;
import org.yanfengying.utils.VerifyCodeUtils;

import java.util.Objects;
import java.util.concurrent.TimeUnit;

@Service
public class VerifyCodeServiceImpl implements IVerifyCodeService {

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private LogininfoMapper logininfoMapper;

    /**
     * 获取验证码
     * @param key
     * @return
     * @throws Exception
     */
    @Override
    public String getImageCode(String key) throws Exception {
        //1 生成随机验证码
        String verifyCode = VerifyCodeUtils.generateVerifyCode(3);

        //2 将验证码放到redis中->设置过期时间->3分钟
        redisTemplate.opsForValue().set(key,verifyCode,3, TimeUnit.MINUTES);
        //3 将验证码合并到图片中,获取base64加密字符
        String code = VerifyCodeUtils.VerifyCode(100, 40, verifyCode);

        //4 将加密字符串返回
        return code;
    }
    /**
     * 注册-发送短信验证码
     * @param dto
     */
    @Override
    public void sendRegisterSmsCode(RegisterSmsDTO dto) {
        //获取参数
        String imageCode = dto.getImageCode();
        String imageCodeKey = dto.getImageCodeKey();
        String mobile = dto.getMobile();
        //参数校验->非空
        if(StringUtils.isEmpty(imageCode) || StringUtils.isEmpty(imageCode) || StringUtils.isEmpty(imageCode)){
            throw new RuntimeException("参数异常,请检查后重新提交");
        }
        //图形验证码是否正确
        String o = (String)redisTemplate.opsForValue().get(imageCodeKey);
        if(StringUtils.isEmpty(o) || !o.equalsIgnoreCase(imageCode)){
            throw new RuntimeException("验证码错误,请重新输入");
        }
        //判断当前手机号是否已经存在验证码
        Logininfo logininfo = logininfoMapper.getPhone(mobile);
        if(Objects.nonNull(logininfo)){
            throw new RuntimeException("该手机号已被注册,请不要重复注册");
        }
        String smsCode = (String)redisTemplate.opsForValue().get("regiser_sms_code_" + mobile);
        String sms = "";
        if(StringUtils.isEmpty(smsCode)){//验证码为空->重新生成验证码
            smsCode = VerifyCodeUtils.generateVerifyCode(3);
        }else {
            //存在->发送原来的验证码->设置过期时间
            smsCode = smsCode.split(":")[0];
            long time = Long.parseLong(smsCode.split(":")[1]);
            //计算是否过期
            if(System.currentTimeMillis() - time < 60*1000){
                throw new RuntimeException("请勿重复操作");
            }

        }
        //将验证码存到redis中
        redisTemplate.opsForValue().set("regiser_sms_code_" +mobile,smsCode+":"+System.currentTimeMillis(),5,TimeUnit.MINUTES );

        //发送短信给用户
        String smsText = "您的验证码是%s,请在%s分钟以内填写";
        System.out.println(smsCode);
//        SmsUtil.sendSms(mobile, String.format(smsText, smsCode,5));
    }

    @Override
    @Transactional
    public void sendBinderSmsCode(BinderDTO dto) {
        //获取参数
        String mobile = dto.getMobile();
        //参数校验->非空
        if(org.springframework.util.StringUtils.isEmpty(mobile)){
            throw new RuntimeException("参数异常,请检查后重新提交");
        }
        String smsCode = (String)redisTemplate.opsForValue().get("binder_sms_code_" + mobile);
        String sms = "";
        if(StringUtils.isEmpty(smsCode)){//验证码为空->重新生成验证码
            smsCode = VerifyCodeUtils.generateVerifyCode(3);
        }else {
            //存在->发送原来的验证码->设置过期时间
            smsCode = smsCode.split(":")[0];
            long time = Long.parseLong(smsCode.split(":")[1]);
            //计算是否过期
            if(System.currentTimeMillis() - time < 60*1000){
                throw new RuntimeException("请勿重复操作");
            }

        }
        //将验证码存到redis中
        redisTemplate.opsForValue().set("binder_sms_code_" + mobile,smsCode+":"+System.currentTimeMillis(),5,TimeUnit.MINUTES );

        //发送短信给用户
        String smsText = "您的验证码是%s,请在%s分钟以内填写";
        System.out.println(smsCode);

    }

    @Override
    public void sendPhoneSmsCode(PhoneLoginDTO dto) {
        //1 参数校验
        String phone = dto.getPhone();
        if(StringUtils.isEmpty(phone)){//空
            throw new RuntimeException("参数异常请重新输入!");
        }
        //2 根据电话号码查询logininfo表数据
        Logininfo logininfo = logininfoMapper.loadByPhone(phone);
        //2.1 判断查询的对象是否为空->空(发出错误信息)->不为空(发送验证码)
        if(Objects.isNull(logininfo)){//为空
            throw new RuntimeException("该手机号不存在或手机号请核对后重新登录!");
        }
        //2.1不为空
        String smsCode = (String)redisTemplate.opsForValue().get("phone_sms_code_" + phone);
        String sms = "";
        if(StringUtils.isEmpty(smsCode)){//验证码为空->重新生成验证码
            smsCode = VerifyCodeUtils.generateVerifyCode(3);
        }else {
            //存在->发送原来的验证码->设置过期时间
            smsCode = smsCode.split(":")[0];
            long time = Long.parseLong(smsCode.split(":")[1]);
            //计算是否过期
            if(System.currentTimeMillis() - time < 60*1000){
                throw new RuntimeException("请勿重复操作");
            }
        }
        //3 将验证码存到redis中
        redisTemplate.opsForValue().set("phone_sms_code_" + phone,smsCode+":"+System.currentTimeMillis(),5,TimeUnit.MINUTES );

        //4 发送短信给用户
        String smsText = "您的验证码是%s,请在%s分钟以内填写";
        System.out.println(smsCode);
    }

    @Override
    public void sendPasswordSmsCode(PasswordDTO dto) {
        //1 参数校验
        String phone = dto.getPhone();
        if(StringUtils.isEmpty(phone)){//空
            throw new RuntimeException("参数异常请重新输入!");
        }
        //2 根据电话号码查询logininfo表数据
        Logininfo logininfo = logininfoMapper.loadByPhone(phone);
        //2.1 判断查询的对象是否为空->空(发出错误信息)->不为空(发送验证码)
        if(Objects.isNull(logininfo)){//为空
            throw new RuntimeException("该手机号不存在或手机号请核对后重新登录!");
        }
        //2.1不为空
        String smsCode = (String)redisTemplate.opsForValue().get("password_sms_code_" + phone);
        String sms = "";
        if(StringUtils.isEmpty(smsCode)){//验证码为空->重新生成验证码
            smsCode = VerifyCodeUtils.generateVerifyCode(3);
        }else {
            //存在->发送原来的验证码->设置过期时间
            smsCode = smsCode.split(":")[0];
            long time = Long.parseLong(smsCode.split(":")[1]);
            //计算是否过期
            if(System.currentTimeMillis() - time < 60*1000){
                throw new RuntimeException("请勿重复操作");
            }
        }
        //3 将验证码存到redis中
        redisTemplate.opsForValue().set("password_sms_code_" + phone,smsCode+":"+System.currentTimeMillis(),5,TimeUnit.MINUTES );
        //4 发送短信给用户
        String smsText = "您的验证码是%s,请在%s分钟以内填写";
        System.out.println(smsCode);
    }
}
